/**
 * 
 */
package cz.cuni.mff.abacs.burglar.logics.objects.positions;

import aStarLibrary.Node;
import cz.cuni.mff.abacs.burglar.logics.DataMap;
import cz.cuni.mff.abacs.burglar.logics.objects.BaseObject;
import cz.cuni.mff.abacs.burglar.logics.objects.Room;


/**
 * 
 * 
 * @author abacs
 *
 */
public abstract class BasePosition extends BaseObject {
	
	/** The room that contains this position.
	 * 
	 * Not changeable property. */
	protected final int _roomId;
	
	/** A* position object
	 * 
	 * Not changeable property. */
	protected Node _node;
	
	
	// -------------------------------------------------------------------------
	// constructors:
	
	
	/**
	 * 
	 * 
	 * @param id
	 * @param objectType
	 * @param x
	 * @param y 
	 * @param isWalkable 
	 * @param room
	 * @param referenceMap
	 */
	protected BasePosition(
			int id,
			BaseObject.Type objectType,
			int x,
			int y,
			boolean isWalkable,
			Room room,
			DataMap referenceMap
	) {
		super(id, objectType, referenceMap);
		this._node = new Node(new float[] {x, y});
		this._node.walkable = isWalkable;
		this._roomId = room.getId();
	}
	
	
	/**
	 * 
	 * 
	 * @param id
	 * @param objectType
	 * @param x
	 * @param y 
	 * @param isWalkable 
	 * @param roomId
	 * @param referenceMap
	 */
	protected BasePosition(
			int id,
			BaseObject.Type objectType,
			int x,
			int y,
			boolean isWalkable,
			int roomId,
			DataMap referenceMap
	) {
		super(id, objectType, referenceMap);
		this._node = new Node(new float[] {x, y});
		this._node.walkable = isWalkable;
		this._roomId = roomId;
	}
	
	
	/**
	 * 
	 * @param other
	 * @param reference
	 */
	protected BasePosition(BasePosition original, DataMap referenceMap) {
		super(original.getId(), original.getType(), referenceMap);
		this._node = new Node(new float[] {original.getX(), original.getY()});
		this._node.walkable = original._node.walkable;
		this._roomId = original._roomId;
	}
	
	
	// -------------------------------------------------------------------------
	
	
	/**
	 * Returns the global x coordinate of the position.
	 * 
	 * @return x coordinate of the position.
	 */
	public int getX() {
		return (int)this._node.p[0];
	}
	
	
	/**
	 * Returns the global y coordinate of the position.
	 * 
	 * @return y coordinate of the position.
	 */
	public int getY() {
		return (int)this._node.p[1];
		
	}
	
	
	// -------------------------------------------------------------------------
	
	
	/** Connects the current position to the parameter position.
	 * 
	 * Expected to be used when initializing the position.
	 * 
	 * @param pos the pother position to connect to.
	 */
	public void connect(BasePosition pos) {
		this._node.connect(pos._node);
	}
	
	
	/**
	 * 
	 */
	public void disconnect() {
		this._node.disconnect();
	}
	
	
	/** Returns the A* node representing the position.
	 * 
	 * For internal use.
	 * 
	 * @return A* node representing the position.
	 */
	public Node getNode() {
		return this._node;
	}
	
	
	// -------------------------------------------------------------------------
	
	
	/**
	 * Returns the room where the position is situated.
	 * 
	 * @return Room object of the position.
	 */
	public Room getRoom() {
		return this._referenceMap.getRoom(this._roomId);
	}
	
	
	
	public int getRoomId() {
		return this._roomId;
	}
	
	
	/**
	 * Returns whether the position is in the selected room.
	 * 
	 * @return true if the position is in the selected room;
	 *         false if the position is not in the selected room.
	 */
	public boolean isInRoom(Room room) {
		if(this._roomId == room.getId())
			return true;
		return false;
	}
	
	
	/**
	 * Returns whether the position is in the selected room.
	 * 
	 * @return true if the position is in the selected room;
	 *         false if the position is not in the selected room.
	 */
	public boolean isInRoom(int roomId) {
		if(this._roomId == roomId)
			return true;
		return false;
	}
	
	
	// -------------------------------------------------------------------------
	
	
	public boolean matches(Position position) {
		return
			this.getId() == position.getId() &&
			this.getType() == position.getType() &&
			this.getX() == position.getX() &&
			this.getY() == position.getY() &&
			this.getRoomId() == position.getRoomId();
	}
	
	
}
